from django.utils import timezone
from .models import Article
from rest_framework import serializers
from .models import Article, ArticleImage, Like
from apps.boards.models import ParentBoard, Board, BoardPostPermission
from ..users.models import TopPostPermission


class ArticleListSerializer(serializers.ModelSerializer):
    """文章列表序列化器"""
    articleId = serializers.IntegerField(source='article_id')
    pBoardId = serializers.IntegerField(source='p_board.p_board_id')
    pBoardName = serializers.CharField(source='p_board_name')
    boardId = serializers.SerializerMethodField()
    boardName = serializers.CharField(source='board_name')
    userId = serializers.IntegerField(source='user.user_id')
    nickName = serializers.CharField(source='nick_name')
    avatar = serializers.CharField(source='user.avatar')
    institution = serializers.CharField(source='user.institution', allow_null=True, allow_blank=True)
    postTime = serializers.DateTimeField(source='post_time', format='%Y-%m-%d %H:%M:%S')
    goodCount = serializers.IntegerField(source='good_count')
    commentCount = serializers.IntegerField(source='comment_count')
    topType = serializers.BooleanField(source='top_type')
    allowComments = serializers.BooleanField(source='allow_comments')
    haveLike = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = [
            'articleId', 'pBoardId', 'pBoardName', 'boardId', 'boardName',
            'userId', 'nickName', 'avatar', 'institution', 'title', 'cover', 'content', 'postTime',
            'goodCount', 'commentCount', 'topType', 'allowComments', 'haveLike'
        ]

    def get_boardId(self, obj):
        """获取板块ID"""
        return obj.board.board_id if obj.board else None

    def get_haveLike(self, obj):
        """当前登录用户是否点赞"""
        request = self.context.get('request')
        if request and hasattr(request, 'user') and request.user.is_authenticated:
            return 1 if Like.objects.filter(
                like_type=0, object_id=obj.article_id, user=request.user
            ).exists() else 0
        return 0


    @staticmethod
    def filter_queryset(params):
        """根据请求参数构建查询集"""
        p_board_id = params.get('pBoardId')
        board_id = params.get('boardId')
        order_type = int(params.get('orderType', 0))

        queryset = Article.objects.all()

        # 筛选
        if p_board_id and int(p_board_id) == 1:
            queryset = queryset.filter(top_type=True)
        elif p_board_id and int(p_board_id) > 0:
            queryset = queryset.filter(p_board__p_board_id=p_board_id)

        if board_id and int(board_id) > 0:
            queryset = queryset.filter(board__board_id=board_id)

        # 排序
        if not (p_board_id and int(p_board_id) == 1):
            if order_type == 0:
                queryset = queryset.order_by('-top_type', '-post_time')
            elif order_type == 1:
                queryset = queryset.order_by('-top_type', '-good_count', '-post_time')
            elif order_type == 2:
                queryset = queryset.order_by('-top_type', '-comment_count', '-post_time')
            else:
                queryset = queryset.order_by('-top_type', '-post_time')
        else:
            if order_type == 0:
                queryset = queryset.order_by('-post_time')
            elif order_type == 1:
                queryset = queryset.order_by('-good_count', '-post_time')
            elif order_type == 2:
                queryset = queryset.order_by('-comment_count', '-post_time')
            else:
                queryset = queryset.order_by('-post_time')

        return queryset


class ArticleDetailSerializer(serializers.ModelSerializer):
    """文章详情序列化器"""
    articleId = serializers.IntegerField(source='article_id')
    pBoardId = serializers.IntegerField(source='p_board.p_board_id')
    pBoardName = serializers.CharField(source='p_board_name')
    boardId = serializers.IntegerField(source='board.board_id')
    boardName = serializers.CharField(source='board_name')
    userId = serializers.IntegerField(source='user.user_id')
    nickName = serializers.CharField(source='nick_name')
    avatar = serializers.CharField(source='user.avatar')
    institution = serializers.CharField(source='user.institution', allow_null=True, allow_blank=True)
    postTime = serializers.DateTimeField(source='post_time', format='%Y-%m-%d %H:%M:%S')
    goodCount = serializers.IntegerField(source='good_count')
    commentCount = serializers.IntegerField(source='comment_count')
    topType = serializers.BooleanField(source='top_type')
    topExpireTime = serializers.DateTimeField(source='top_expire_time', format='%Y-%m-%d %H:%M:%S', allow_null=True)
    expireTime = serializers.DateTimeField(source='expire_time', format='%Y-%m-%d %H:%M:%S', allow_null=True)
    allowComments = serializers.BooleanField(source='allow_comments')
    imageList = serializers.SerializerMethodField()
    haveLike = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = [
            'articleId', 'pBoardId', 'pBoardName', 'boardId', 'boardName',
            'userId', 'nickName', 'avatar', 'institution', 'title', 'content', 'postTime',
            'goodCount', 'commentCount', 'topType', 'topExpireTime', 'expireTime', 'allowComments',
            'imageList', 'haveLike'
        ]

    def get_imageList(self, obj):
        """返回图片列表"""
        return [img.image_path for img in obj.images.all()]

    def get_haveLike(self, obj):
        """当前登录用户是否点赞该文章"""
        request = self.context.get('request')
        if request and hasattr(request, 'user') and request.user.is_authenticated:
            return Like.objects.filter(
                like_type=0, object_id=obj.article_id, user=request.user
            ).exists()
        return False


    @staticmethod
    def get_article_detail(article_id):
        """获取文章详情对象"""
        article = (
            Article.objects
            .select_related('user', 'p_board', 'board')
            .prefetch_related('images')
            .filter(article_id=article_id)
            .first()
        )
        return article


class ArticleCreateSerializer(serializers.ModelSerializer):
    """文章创建序列化器"""
    pBoardId = serializers.IntegerField(source='p_board_id', write_only=True)
    boardId = serializers.IntegerField(source='board_id', write_only=True, required=False)
    topType = serializers.BooleanField(source='top_type', required=False, default=False)
    topExpireTime = serializers.DateTimeField(source='top_expire_time', required=False, allow_null=True)
    expireTime = serializers.DateTimeField(source='expire_time', required=False, allow_null=True)
    allowComments = serializers.BooleanField(source='allow_comments', required=False, default=True)
    imageList = serializers.ListField(
        child=serializers.CharField(),
        write_only=True,
        required=False
    )

    class Meta:
        model = Article
        fields = ['pBoardId', 'boardId', 'title', 'content',
                  'topType', 'topExpireTime', 'expireTime', 'allowComments', 'imageList']


    def validate(self, data):
        """整体逻辑验证"""
        request = self.context.get('request')
        if not request or not request.user.is_authenticated:
            raise serializers.ValidationError("User authentication required")

        user = request.user

        # 检查板块合法性
        p_board_id = data.get('p_board_id')
        board_id = data.get('board_id')

        if p_board_id:
            try:
                p_board = ParentBoard.objects.get(p_board_id=p_board_id)
            except ParentBoard.DoesNotExist:
                raise serializers.ValidationError("The parent board does not exist")

            # 验证boardId是否在pBoardId下存在
            if board_id:
                try:
                    board = Board.objects.get(board_id=board_id, p_board=p_board)
                except Board.DoesNotExist:
                    raise serializers.ValidationError("The board does not exist under the specified parent board")

            # 如果板块需要权限
            if p_board.require_permission:
                has_permission = BoardPostPermission.objects.filter(
                    p_board=p_board,
                    user=user,
                    is_active=True
                ).exists()
                if not has_permission:
                    raise serializers.ValidationError(f"You do not have permission to post in '{p_board.board_name}' board")

        # 检查置顶逻辑
        top_type = data.get('top_type', False)
        top_expire_time = data.get('top_expire_time')

        # 如果不置顶，自动清空过期时间
        if not top_type:
            data['top_expire_time'] = None
            top_expire_time = None

        # 检查置顶权限
        if top_type:
            if not (user.is_staff or user.is_superuser):
                has_top_permission = TopPostPermission.objects.filter(
                    user=user,
                    is_active=True
                ).exists()
                if not has_top_permission:
                    raise serializers.ValidationError("You do not have permission to post Notice posts")

        # 检查置顶到期
        if top_expire_time is not None and not top_type:
            raise serializers.ValidationError("topExpireTime can only be set when topType is True")

        if top_expire_time is not None and top_expire_time <= timezone.now():
            raise serializers.ValidationError("Notice expire time cannot be earlier than current time")

        # 检查文章到期时间
        expire_time = data.get('expire_time')
        if expire_time is not None and expire_time <= timezone.now():
            raise serializers.ValidationError("Article expire time must be later than current time")

        return data


    def create(self, validated_data):
        """创建文章"""
        image_list = validated_data.pop('imageList', [])
        p_board_id = validated_data.pop('p_board_id')
        board_id = validated_data.pop('board_id', None)

        request = self.context.get('request')
        user = request.user

        # 获取板块对象
        p_board = ParentBoard.objects.get(p_board_id=p_board_id)
        board = Board.objects.get(board_id=board_id) if board_id else None

        # 创建文章
        article = Article.objects.create(
            user=user,
            p_board=p_board,
            board=board,
            **validated_data
        )

        # 创建图片记录
        for image_path in image_list:
            ArticleImage.objects.create(article=article, image_path=image_path)

        # 标记临时图片为已使用
        if image_list:
            # 设置封面为第一张图片
            article.cover = image_list[0]
            article.save()

        return article

class ArticleUpdateSerializer(serializers.ModelSerializer):
    """文章更新序列化器"""
    pBoardId = serializers.IntegerField(source='p_board_id', write_only=True, required=False)
    boardId = serializers.IntegerField(source='board_id', write_only=True, required=False)
    articleId = serializers.IntegerField(source='article_id', write_only=True)
    topType = serializers.BooleanField(source='top_type', required=False)
    topExpireTime = serializers.DateTimeField(source='top_expire_time', required=False, allow_null=True)
    expireTime = serializers.DateTimeField(source='expire_time', required=False, allow_null=True)
    allowComments = serializers.BooleanField(source='allow_comments', required=False)
    imageList = serializers.ListField(
        child=serializers.CharField(),
        write_only=True,
        required=False
    )

    class Meta:
        model = Article
        fields = [
            'pBoardId', 'boardId', 'articleId', 'title', 'content',
            'topType', 'topExpireTime', 'expireTime', 'allowComments', 'imageList'
        ]


    def validate(self, data):
        """整体逻辑验证"""
        request = self.context.get('request')
        if not request or not request.user.is_authenticated:
            raise serializers.ValidationError("User authentication required")

        user = request.user

        # 查找文章实例
        article_id = data.get('article_id')
        if not article_id:
            raise serializers.ValidationError("Article ID cannot be empty")

        try:
            instance = Article.objects.get(article_id=article_id)
        except Article.DoesNotExist:
            raise serializers.ValidationError("The article does not exist")

        self.instance = instance

        # 验证用户是否作者
        if instance.user_id != user.user_id:
            raise serializers.ValidationError("No permission to modify this article")

        # 检查板块合法性
        p_board_id = data.get('p_board_id')
        board_id = data.get('board_id')

        if p_board_id:
            try:
                p_board = ParentBoard.objects.get(p_board_id=p_board_id)
            except ParentBoard.DoesNotExist:
                raise serializers.ValidationError("The parent board does not exist")

            # 验证boardId是否在pBoardId下存在
            if board_id:
                try:
                    board = Board.objects.get(board_id=board_id, p_board=p_board)
                except Board.DoesNotExist:
                    raise serializers.ValidationError("The board does not exist under the specified parent board")

            # 如果板块需要权限
            if p_board.require_permission:
                has_permission = BoardPostPermission.objects.filter(
                    p_board=p_board,
                    user=user,
                    is_active=True
                ).exists()
                if not has_permission:
                    raise serializers.ValidationError(f"You do not have permission to post in '{p_board.board_name}' board")

        # 检查置顶逻辑
        top_type = data.get('top_type', instance.top_type)
        top_expire_time = data.get('top_expire_time', instance.top_expire_time)
        expire_time = data.get('expire_time', instance.expire_time)

        # 如果不置顶，自动清空过期时间
        if 'top_type' in data and not top_type:
            data['top_expire_time'] = None
            top_expire_time = None

        # 检查置顶权限
        if top_type and not (user.is_staff or user.is_superuser):
            has_top_permission = TopPostPermission.objects.filter(
                user=user,
                is_active=True
            ).exists()
            if not has_top_permission:
                raise serializers.ValidationError("You do not have permission to post Notice posts")

        # 检查置顶到期逻辑
        if top_expire_time is not None and not top_type:
            raise serializers.ValidationError("Notice expire time can only be set when topType is True")

        if top_expire_time is not None and top_expire_time <= timezone.now():
            raise serializers.ValidationError("Notice expire time cannot be earlier than current time")

        # 检查文章到期时间
        if expire_time is not None and expire_time <= timezone.now():
            raise serializers.ValidationError("Article expire time must be later than current time")

        return data


    def update(self, instance, validated_data):
        """ 更新文章 """
        img_list = validated_data.pop('imageList', None)
        p_board_id = validated_data.pop('p_board_id', None)
        board_id = validated_data.pop('board_id', None)
        validated_data.pop('article_id', None)

        # 更新板块信息
        if p_board_id:
            instance.p_board = ParentBoard.objects.get(p_board_id=p_board_id)
        if board_id:
            instance.board = Board.objects.get(board_id=board_id)

        # 更新普通字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        # 更新图片
        if img_list is not None:
            # 删除旧图片
            instance.images.all().delete()

            # 创建新图片
            for image_path in img_list:
                ArticleImage.objects.create(article=instance, image_path=image_path)

            # 标记临时图片为已使用
            if img_list:
                # 设置封面
                instance.cover = img_list[0]
            else:
                # 当更新后没有任何图片时，清空封面
                instance.cover = None

        instance.save()
        return instance

class BoardSerializer(serializers.ModelSerializer):
    """板块序列化器"""
    pBoardId = serializers.IntegerField(source='p_board_id')
    boardName = serializers.CharField(source='board_name')
    sort = serializers.SerializerMethodField()
    children = serializers.SerializerMethodField()

    class Meta:
        model = ParentBoard
        fields = ['pBoardId', 'boardName', 'sort', 'children']

    def get_sort(self, obj):
        return 1  # 默认排序

    def get_children(self, obj):
        children = []
        for board in obj.children.all():
            children.append({
                'boardId': board.board_id,
                'boardName': board.board_name,
                'sort': 1
            })
        return children